﻿using EFFC.Frame.Net.Module.Extend.EWRA.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EFFC.Extends.LinqDLR2SQL;
using EFFC.Frame.Net.Base.Data.Base;
using EFFC.Frame.Net.Module.Extend.EWRA.Attributes.Validation;
using EFFC.Frame.Net.Base.Common;
using EFFC.Frame.Net.Base.Data;
using EFFC.Frame.Net.Unit.DB;
using EFFC.Frame.Net.Unit.DB.Parameters;
using ICPFrameLib.Attributes;
using ICPFrameLib.Business;
using EFFC.Extends.HostJs.HostJsObject;
using System.IO;
using Frame.Net.Base.Exceptions;

namespace XHRPMIS.Business.v1._0
{
     public class HostJs : MyRestLogic
{
    [EWRAAuth(true)]
    [ActionAuth("HostJs")]
    [EWRARoute("get", "/hj/doc")]
    [EWRARouteDesc("获取hostjs的开发文档")]
    [EWRAOutputDesc("返回结果", @"{
    code:""success-成功，failed-失败"",
    msg:""提示信息"",
    data:'Hostjs sdk相关文档'
    }")]
    public object GetHostJsSDKDoc()
    {
        //SetCacheEnable(false);
        using (var hje = HostScript.GetHostLogicEngine())
        {
            return new
            {
                code = "success",
                msg = "",
                data = new
                {
                    host_objects = (from t in hje.CurrentContext.AllHostJsObject
                                    select t.ConstructorDesc).ToList(),
                    host_tags = (from t in hje.CurrentContext.AllTags
                                 select t.ToJsonObject()).ToList()
                }
            };
        }
    }
    [EWRAAuth(true)]
    [ActionAuth("HostJs")]
    [EWRARoute("get", "/hj/source/list")]
    [EWRARouteDesc("获取hostjs的源码列表")]
    [EWRAOutputDesc("返回结果", @"{
    code:""success-成功，failed-失败"",
    msg:""提示信息"",
    data:['名称列表']
    }")]
    public object GetSourceList()
    {
        SetCacheEnable(false);
        using (var hje = HostScript.GetHostLogicEngine())
        {
            return new
            {
                code = "success",
                msg = "",
                data = hje.GetSourceList()
            };
        }
    }
    [EWRAAuth(true)]
    [ActionAuth("HostJs")]
    [EWRARoute("get", "/hj/commlib/list")]
    [EWRARouteDesc("获取hostjs的commlib库列表")]
    [EWRAOutputDesc("返回结果", @"{
    code:""success-成功，failed-失败"",
    msg:""提示信息"",
    data:['名称列表']
    }")]
    public object GetCommlibList()
    {
        SetCacheEnable(false);
        using (var hje = HostScript.GetHostLogicEngine())
        {
            return new
            {
                code = "success",
                msg = "",
                data = hje.GetCommLibList()
            };
        }
    }
    [EWRAAuth(true)]
    [ActionAuth("HostJs")]
    [EWRARoute("get", "/hj/compiled/list")]
    [EWRARouteDesc("获取hostjs的compiled列表")]
    [EWRAOutputDesc("返回结果", @"{
    code:""success-成功，failed-失败"",
    msg:""提示信息"",
    data:['名称列表']
    }")]
    public object GetCompiledList()
    {
        SetCacheEnable(false);
        using (var hje = HostScript.GetHostLogicEngine())
        {
            return new
            {
                code = "success",
                msg = "",
                data = hje.GetCompiledList()
            };
        }
    }
    [EWRAAuth(true)]
    [ActionAuth("HostJs")]
    [EWRARoute("get", "/hj/source/content")]
    [EWRARouteDesc("获取hostjs的指定源码内容")]
    [EWRAAddInput("name", "string", "脚本名称", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.QueryString, false)]
    [EWRAOutputDesc("返回结果", @"{
    code:""success-成功，failed-失败"",
    msg:""提示信息"",
    data:{
        content:'源代码内容'
    }
    }")]
    public object GetSourceContent()
    {
        SetCacheEnable(false);
        using (var hje = HostScript.GetHostLogicEngine())
        {
            return new
            {
                code = "success",
                msg = "",
                data = new
                {
                    content = hje.Read(ComFunc.nvl(QueryStringD.name))
                }
            };
        }
    }
    [EWRAAuth(true)]
    [ActionAuth("HostJs")]
    [EWRARoute("get", "/hj/commlib/content")]
    [EWRARouteDesc("获取hostjs的指定Commlib内容")]
    [EWRAAddInput("name", "string", "脚本名称", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.QueryString, false)]
    [EWRAOutputDesc("返回结果", @"{
    code:""success-成功，failed-失败"",
    msg:""提示信息"",
    data:{
        content:'源代码内容'
    }
    }")]
    public object GetCommlibContent()
    {
        SetCacheEnable(false);
        using (var hje = HostScript.GetHostLogicEngine())
        {
            return new
            {
                code = "success",
                msg = "",
                data = new
                {
                    content = hje.ReadCommLibSource(ComFunc.nvl(QueryStringD.name))
                }
            };
        }
    }
    [EWRAAuth(true)]
    [ActionAuth("HostJs")]
    [EWRARoute("get", "/hj/compiled/content")]
    [EWRARouteDesc("获取hostjs的指定compiled内容")]
    [EWRAAddInput("name", "string", "脚本名称", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.QueryString, false)]
    [EWRAOutputDesc("返回结果", @"{
    code:""success-成功，failed-失败"",
    msg:""提示信息"",
    data:{
        content:'源代码内容'
    }
    }")]
    public object GetCompiledContent()
    {
        SetCacheEnable(false);
        using (var hje = HostScript.GetHostLogicEngine())
        {
            return new
            {
                code = "success",
                msg = "",
                data = new
                {
                    content = hje.ReadCompiledSource(ComFunc.nvl(QueryStringD.name))
                }
            };
        }
    }
    [EWRAAuth(true)]
    [ActionAuth("HostJs")]
    [EWRARoute("post", "/hj/save")]
    [EWRARouteDesc("保存hostjs脚本代码")]
    [EWRAEmptyValid("name,content")]
    [EWRAAddInput("name", "string", "脚本名称", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.PostData, false)]
    [EWRAAddInput("content", "string", "脚本内容", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.PostData, false)]
    [EWRAOutputDesc("返回结果", @"{
    code:""success-成功，failed-失败"",
    msg:""提示信息""
    }")]
    public object SaveScripts()
    {
        using (var hje = HostScript.GetHostLogicEngine())
        {
            var msg = "";
            if (!hje.Save(ComFunc.nvl(PostDataD.name), ComFunc.nvl(PostDataD.content), ref msg))
            {
                return new
                {
                    code = "failed",
                    msg
                };
            }
            else
            {
                return new
                {
                    code = "success",
                    msg = "操作成功"
                };
            }
        }
    }
    [EWRAAuth(true)]
    [ActionAuth("HostJs")]
    [EWRARoute("post", "/hj/compile")]
    [EWRARouteDesc("编译hostjs脚本代码")]
    [EWRAEmptyValid("name")]
    [EWRAAddInput("name", "string", "脚本名称", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.PostData, false)]
    [EWRAOutputDesc("返回结果", @"{
    code:""success-成功，failed-失败"",
    msg:""提示信息""
    }")]
    public object CompileScript()
    {
        using (var hje = HostScript.GetHostLogicEngine())
        {
            var msg = "";
            string content = hje.Read(ComFunc.nvl(PostDataD.name));
            if (string.IsNullOrEmpty(content)) return new
            {
                code = "failed",
                msg = "无该文件或内容为空"
            };
            hje.Compile(ComFunc.nvl(PostDataD.name), content, true);

            return new
            {
                code = "success",
                msg = "操作成功"
            };
        }
    }
    [EWRAAuth(true)]
    [ActionAuth("HostJs")]
    [EWRARoute("post", "/hj/compileall")]
    [EWRARouteDesc("编译所有的hostjs脚本代码")]
    [EWRAOutputDesc("返回结果", @"{
    code:""success-成功，failed-失败"",
    msg:""提示信息""
    }")]
    public object CompileAllScript()
    {
        using (var hje = HostScript.GetHostLogicEngine())
        {
            var msg = "";
            foreach (var name in hje.GetSourceList())
            {
                string content = hje.Read(Path.GetFileName(name));
                if (string.IsNullOrEmpty(content)) return new
                {
                    code = "failed",
                    msg = "无该文件或内容为空"
                };
                hje.Compile(Path.GetFileName(name), content, true);
            }

            return new
            {
                code = "success",
                msg = "操作成功"
            };
        }
    }
    [EWRAAuth(true)]
    [ActionAuth("HostJs")]
    [EWRARoute("post", "/hj/save_compile")]
    [EWRARouteDesc("保存并编译hostjs脚本代码")]
    [EWRAEmptyValid("name,content")]
    [EWRAAddInput("name", "string", "脚本名称", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.PostData, false)]
    [EWRAAddInput("content", "string", "脚本内容", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.PostData, false)]
    [EWRAOutputDesc("返回结果", @"{
    code:""success-成功，failed-失败"",
    msg:""提示信息""
    }")]
    public object SaveAndCompileScript()
    {
        using (var hje = HostScript.GetHostLogicEngine())
        {
            var msg = "";
            if (!hje.Save(ComFunc.nvl(PostDataD.name), ComFunc.nvl(PostDataD.content), ref msg))
            {
                return new
                {
                    code = "failed",
                    msg
                };
            }
            hje.Compile(ComFunc.nvl(PostDataD.name), ComFunc.nvl(PostDataD.content), true);

            return new
            {
                code = "success",
                msg = "操作成功"
            };
        }
    }
    [EWRAAuth(true)]
    [ActionAuth("HostJs")]
    [EWRARoute("post", "/hj/tryrun")]
    [EWRARouteDesc("尝试运行脚本并获得结果")]
    [EWRAEmptyValid("content")]
    [EWRAAddInput("content", "string", "脚本内容", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.PostData, false)]
    [EWRAOutputDesc("返回结果", @"{
    code:""success-成功，failed-失败"",
    msg:""提示信息"",
    data:{
        run_result:'运行后返回的结果数据'
    }
    }")]
    public object Run()
    {
        string content = ComFunc.nvl(PostDataD.content);
        using (var hje = HostScript.GetHostLogicEngine())
        {
            try
            {
                var re = hje.RunFormatJs(content);
                //重新设置返回结果类型，防止执行的脚本会修改返回结果状态
                SetContentType(EFFC.Frame.Net.Module.Extend.EWRA.Constants.RestContentType.JSON);
                return new
                {
                    code = "success",
                    msg = "操作成功",
                    data = new
                    {
                        run_result = re
                    }
                };
            }
            catch (HostJsException ex)
            {
                return new
                {
                    code = "faild",
                    msg = $"{ex.Message}"
                };
            }
        }
    }
    [EWRAAuth(true)]
    [EWRARoute("post", "/callhjs/{name}/{action}")]
    [EWRARouteDesc("尝试运行脚本并获得结果")]
    [EWRAAddInput("name", "string", "脚本名称", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.Path, false)]
    [EWRAAddInput("action", "string", "操作", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.Path, false)]
    [EWRAOutputDesc("返回结果", @"执行脚本返回的结果")]
    public object PostCall(string name, string action)
    {
        return Call(name, action);
    }
    [EWRAAuth(true)]
    [EWRARoute("post", "/callhjs/{name}")]
    [EWRARouteDesc("尝试运行脚本并获得结果")]
    [EWRAAddInput("name", "string", "脚本名称", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.Path, false)]
    [EWRAOutputDesc("返回结果", @"执行脚本返回的结果")]
    public object PostCall(string name)
    {
        return Call(name);
    }
    [EWRAAuth(true)]
    [EWRARoute("get", "/callhjs/{name}/{action}")]
    [EWRARouteDesc("尝试运行脚本并获得结果")]
    [EWRAAddInput("name", "string", "脚本名称", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.Path, false)]
    [EWRAOutputDesc("返回结果", @"执行脚本返回的结果")]
    public object GetCall(string name, string action)
    {
        SetCacheEnable(false);
        return Call(name, action);
    }
    [EWRAAuth(true)]
    [EWRARoute("get", "/callhjs/{name}")]
    [EWRARouteDesc("尝试运行脚本并获得结果")]
    [EWRAAddInput("name", "string", "脚本名称", "无默认值", EFFC.Frame.Net.Base.Constants.RestInputPosition.Path, false)]
    [EWRAOutputDesc("返回结果", @"执行脚本返回的结果")]
    public object GetCall(string name)
    {
        SetCacheEnable(false);
        return Call(name);
    }
    private object Call(string name, string action = "")
    {
        var fname = $"{name}.{action}";
        if (string.IsNullOrEmpty(action)) fname = name;
        using (var hje = HostScript.GetHostLogicEngine())
        {
            var content = hje.ReadCompiledSource(fname);
            if (string.IsNullOrEmpty(content)) return new
            {
                code = "failed",
                msg = "执行失败：无可执行代码"
            };
            try
            {
                var rtn = hje.RunFormatJs(content);
                return rtn;
            }
            finally
            {
                Console.Write((hje.CurrentContext.GetHostJsObject("ConsoleS") as ConsoleObject).OutMsg);
                (hje.CurrentContext.GetHostJsObject("ConsoleS") as ConsoleObject).Clear();
            }


        }
    }
}
}
